﻿using System;
using ufida.u9.ait.openapi.utils;
using UFIDA.U9.AP.Payment;
using UFIDA.U9.Base;
using UFIDA.U9.Base.Currency;
using UFIDA.U9.CBO.FI.BankAccount;
using UFIDA.U9.CBO.FI.DTOs;
using UFIDA.U9.CBO.FI.Enums;
using UFIDA.U9.CBO.FI.IncExpItem;
using UFIDA.U9.CBO.FI.SettlementMethod;
using UFIDA.U9.CBO.HR.Department;
using UFIDA.U9.CBO.HR.Operator;
using UFIDA.U9.CBO.SCM.ProjectTask;
using UFIDA.U9.CBO.SCM.Supplier;
using UFSoft.UBF.Business;

namespace ufida.u9.ait.openapi
{
    internal class PayBillBase
    {
        public static PayBillHead ApproveDoc(PayBillHead doc)
        {
            //重新加载实体,否则报错 并发异常
            doc = doc.Key.GetEntity();

            //调用BE自带审核方法
            if(doc.DocStatus== BillStatusEnum.Approved)
                throw new Exception($"单号:[{doc.DocNo}]状态已审,不能重复审批");

            doc.DoApproving();
            return doc;
        }

        public static PayBillHead CreateDoc(PayBillHeadAITDTOData dto)
        {
            PayBillHead doc;
            using (ISession session = Session.Open())
            {
                doc = PayBillHead.Create();
                CreateHead(doc, dto);
                CreateLine(doc, dto);

                session.Commit();
            }
            return doc;
        }

        private static void CreateLine(PayBillHead doc, PayBillHeadAITDTOData dto)
        {
            int LineNum = 0;
            foreach (var dto1 in dto.PayBillLines)
            {
                LineNum += 10;

                //校验
                if (dto1.Money == 0)
                    throw new Exception("行金额为0");
                if (dto1.SettlementMethod == null)
                    throw new Exception("结算方式为空");

                //赋值
                PayBillLine line = PayBillLine.Create(doc);
                if (dto1.LineNum > 0)
                    line.LineNum = dto1.LineNum;
                else
                    line.LineNum = LineNum;
                //结算方式
                line.SettlementMethod = EntityUtils.GetEntityByCode<SettlementMethod>(dto1.SettlementMethod);
                line.SettlementMethodClass = line.SettlementMethod.SettlementClass;
                //金额
                line.Money = new UFIDA.U9.CBO.FI.PropertyTypes.FAMoney() { OCMoney = dto1.Money, FCMoney = dto1.Money };
                line.TotalMoney = line.Money;
                line.TotalBalance = line.Money;
                //银行,账号
                line.PayBkAcc = EntityUtils.GetEntityByCode<BankAccount>(dto1.PayBkAcc);
                if (line.PayBkAcc != null)
                {
                    line.PayBkAccName = line.PayBkAcc.Name;
                    line.PayBk = line.PayBkAcc.Bank;
                    line.PayBAC = doc.AC;
                }
                //收款银行,账号
                line.RecBk = dto1.RecBk;
                line.RecBkAccount = dto1.RecBkAccount;
                line.RecBkAccName = dto1.RecBkAccName;
                line.RecCardNum = dto1.RecCardNum;
                if (!String.IsNullOrEmpty(line.RecBkAccount))
                {
                    //收款账号非空，需要新增供应商银行账号
                    if (String.IsNullOrEmpty(dto1.RecBkCode))
                        throw new Exception("收款银行编码[RecBkCode]为空！");
                    //BankAccount recAcc = BankAccount.Finder.Find($"Code='{line.RecBkAccount}'", null);
                    SupplierBankAccount sba = SupplierBankAccount.Finder.Find($"Code='{line.RecBkAccount}' and Supplier='{doc.Supp.Supplier.ID}'", null);
                    if (sba == null)
                    {
                        //创建银行账号实体
                        using (ISession se = Session.Open())
                        {
                            //供应商银行账户
                            sba = SupplierBankAccount.Create(doc.Supp.Supplier);
                            sba.Code = line.RecBkAccount;
                            sba.Name = line.RecBkAccName;
                            sba.Bank = EntityUtils.GetEntityByCode<Bank>(dto1.RecBkCode);
                            sba.IsDefault = false;
                            sba.IsMultiCurrency = false;
                            //供应商账号币种
                            SupplierAccountCurrency sac = SupplierAccountCurrency.Create(sba);
                            sac.Currency = EntityUtils.GetEntityByCode<Currency>("C001");
                            sac.IsDefault = true;

                            //下述注释掉,因为在创建[供应商银行账户]时,下述会自动创建
                            ////银行账号
                            //recAcc = BankAccount.Create();
                            //recAcc.Bank = EntityUtils.GetEntityByCode<Bank>(dto1.RecBkCode);
                            //recAcc.UserType = UserTypeEnum.Supplier;
                            //recAcc.Org = doc.Org;
                            //recAcc.CreateOrg = doc.Org;
                            //recAcc.Supplier = doc.Supp.Supplier;
                            //recAcc.IsMultiCurrencies = false;
                            //recAcc.IsBaseAccount= false;
                            //recAcc.Code = line.RecBkAccount;
                            //recAcc.Name = line.RecBkAccName;
                            //recAcc.IsDefaultBankAccount= false;
                            //recAcc.AccountType = AccountTypeEnum.Balance;
                            //recAcc.IncExpDirect = IncExpDirectEnum.IncExp;
                            //recAcc.AccountState = AccountStateEnum.Normal;
                            //recAcc.OpenDate= DateTime.Now;
                            ////银行账号币种关系
                            //BankAccountCurrencyRelation rel = BankAccountCurrencyRelation.Create(recAcc);
                            //rel.Currency = EntityUtils.GetEntityByCode<Currency>("C001");
                            //rel.MinMoneyControlType = MinMaxCtrlTypeEnum.NoControl;
                            //rel.MaxMoneyControlType= MinMaxCtrlTypeEnum.NoControl;
                            //rel.IsDefault = true;

                            se.Commit();
                        }
                    }
                }

                //扩展字段处理
                if (dto1.DescFlexField != null)
                {
                    line.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
                    DTOUtils.DTOPropCopy(dto1.DescFlexField, line.DescFlexField);
                }

                //其他
                line.PCToFCExRate = 1;
                line.IncomeExpendItem = EntityUtils.GetEntityByCode<IncExpItem>(dto1.IncomeExpendItem);

                //创建用途子行
                CreateUseLine(line, dto1);
            }

        }

        private static void CreateUseLine(PayBillLine line, PayBillLineAITDTOData linedto)
        {
            PayBillHead doc = line.PayBillHead;
            if (linedto.PayBillUseLines == null || linedto.PayBillUseLines.Count == 0)
            {
                //传入用途为空
                PayBillUseLine line1 = PayBillUseLine.Create(line);
                line1.PayBillHead = doc;
                line1.PayProperty = PayPropertyEnum.GetFromValue(linedto.PayProperty);//用途 默认=标准
                line1.Project = EntityUtils.GetEntityByCode<Project>(linedto.Project);//项目
                line1.Transactor = doc.Transactor;//业务员
                line1.TotalMoney = line.TotalMoney;//总金额
                line1.TotalBalance = line.TotalBalance;//总金额余额
                line1.Money = line.Money;//金额
                line1.ACTotalMoney = line.Money.OCMoney;//总金额
                line1.SuppSite = doc.SuppSite;//供应商位置
                line1.Supp = doc.Supp;//供应商
                line1.SrcBillOrg = doc.SrcBillOrg;//来源组织
                line1.LineNum = 10;//行号
                line1.IncomeExpendItem = line.IncomeExpendItem;//收支项目
                line1.Dept = doc.Dept;//部门
                line1.BizOrg = doc.BizOrg;//业务组织
                line1.EffectiveDate = doc.PayDate;//到期日
            }
            else
            {
                int rowno = 0;
                //传入用途
                foreach(var usedto in linedto.PayBillUseLines)
                {
                    rowno += 10;
                    PayBillUseLine line1 = PayBillUseLine.Create(line);
                    line1.PayBillHead = doc;
                    if (usedto.PayProperty >= 0)
                    {
                        line1.PayProperty = PayPropertyEnum.GetFromValue(usedto.PayProperty);//用途 默认=标准
                    }
                    else
                    {
                        line1.PayProperty = PayPropertyEnum.GetFromValue(linedto.PayProperty);//用途 默认=标准
                    }
                    if (usedto.IncomeExpendItem != null && !string.IsNullOrEmpty(usedto.IncomeExpendItem.Code))
                    {
                        //收支项目
                        line1.IncomeExpendItem=EntityUtils.GetEntityByCode<IncExpItem>(usedto.IncomeExpendItem.Code);
                    }
                    else
                    {
                        line1.IncomeExpendItem = line.IncomeExpendItem;//收支项目
                    }
                    if (usedto.Project != null && !string.IsNullOrEmpty(usedto.Project.Code))
                    {
                        line1.Project = EntityUtils.GetEntityByCode<Project>(usedto.Project);//项目
                    }
                    else
                    {
                        line1.Project = EntityUtils.GetEntityByCode<Project>(linedto.Project);//项目
                    }
                    if (usedto.Transactor != null && !string.IsNullOrEmpty(usedto.Transactor.Code))
                    {
                        line1.Transactor=EntityUtils.GetEntityByCode<Operators>(usedto.Transactor);//业务员
                    }
                    else
                    {
                        line1.Transactor = doc.Transactor;//业务员
                    }
                    if (!string.IsNullOrEmpty(usedto.Dept?.Code))
                    {
                        line1.Dept=EntityUtils.GetEntityByCode<Department>(usedto.Dept.Code);//部门
                    }
                    else
                    {
                        line1.Dept = doc.Dept;//部门
                    }

                    //金额
                    line1.Money = new UFIDA.U9.CBO.FI.PropertyTypes.FAMoney() { FCMoney = usedto.Money, OCMoney = usedto.Money };
                    line1.TotalMoney = line1.Money;
                    line1.TotalBalance = line1.Money;//总金额余额
                    line1.ACTotalMoney = usedto.Money;//总金额

                    //其他
                    line1.LineNum = rowno;//行号
                    line1.SuppSite = doc.SuppSite;//供应商位置
                    line1.Supp = doc.Supp;//供应商
                    line1.SrcBillOrg = doc.SrcBillOrg;//来源组织
                    line1.BizOrg = doc.BizOrg;//业务组织
                    line1.EffectiveDate = doc.PayDate;//到期日
                }
            }
            
        }

        private static void CreateHead(PayBillHead doc, PayBillHeadAITDTOData dto)
        {
            //校验
            if (String.IsNullOrEmpty(dto.DocNo))
                throw new Exception("单号必须传入");
            if (dto.Supp == null)
            {
                throw new Exception("供应商必须传入");
            }

            //doc.DocNo = dto.DocNo;
            if (String.IsNullOrEmpty(dto.PayDate)) throw new Exception("PayDate必填!");
            doc.PayDate = DateTime.Parse(dto.PayDate);//付款日期
            doc.PostPeriod = EntityUtils.getPostPeriod(doc.PayDate);//期间
            doc.PayObjType = RecPayObjectTypeEnum.GetFromValue(dto.PayObjType);//付款对象
            if (string.IsNullOrEmpty(dto.DocumentType?.Code)) throw new Exception("DocumentType为空");
            doc.DocumentType = EntityUtils.GetEntityByCode<PayDocType>(dto.DocumentType);//单据类型

            //赋值
            //组织
            doc.Org = Context.LoginOrg;
            doc.SrcBillOrg = Context.LoginOrg;
            doc.SettleOrg = Context.LoginOrg;
            doc.BizOrg = Context.LoginOrg;

            //供应商
            Supplier supplier = EntityUtils.GetEntityByCode<Supplier>(dto.Supp.Code);
            doc.Supp = new SupplierMISCInfo()
            {
                Supplier = supplier,
                ShortName = supplier.ShortName,
                Name = supplier.Name,
                Code = supplier.Code,
            };
            if (supplier.SupplierSites != null && supplier.SupplierSites.Count > 0)
            {
                doc.SuppSite = new SupplierSiteMISCInfo()
                {
                    SupplierSite = supplier.SupplierSites[0],
                    Name = supplier.SupplierSites[0].Name,
                    Code = supplier.SupplierSites[0].Code,
                };
            }
            //扩展字段处理
            if (dto.DescFlexField != null)
            {
                doc.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
                DTOUtils.DTOPropCopy(dto.DescFlexField, doc.DescFlexField);
            }

            //其他
            doc.Transactor = EntityUtils.GetEntityByCode<Operators>(dto.Transactor);//人员
            //部门
            if (!string.IsNullOrEmpty(dto.Dept?.Code))
            {
                doc.Dept = EntityUtils.GetEntityByCode<Department>(dto.Dept.Code);
            }
            else
            {
                if (doc.Transactor != null)
                {
                    doc.Dept = doc.Transactor.Dept;//部门=业务员.部门
                }
            }
            doc.PCToFCExRate = 1;
            doc.PCToACExRate = 1;
            //币种
            if (dto.PC == null)
                doc.PC = EntityUtils.GetEntityByCode<Currency>("C001");
            else
                doc.PC = EntityUtils.GetEntityByCode<Currency>(dto.PC);
            doc.AC = doc.PC;
            doc.Memo = dto.Memo;
            doc.Project=EntityUtils.GetEntityByCode<Project>(dto.Project);//项目
        }
    }
}
